Что такое кэширование и revalidation в React Server Components?
React Server Components: кэширование и revalidation
React Server Components (RSC) — это компоненты, которые рендерятся на сервере и не отправляют свой JS-код на клиент. Поскольку рендеринг происходит на сервере при каждом запросе, фреймворки (например, Next.js) добавляют слой кэширования, чтобы не пересчитывать одно и то же снова и снова.
Зачем нужно кэширование
Без кэша каждый переход по странице или запрос данных заново обращался бы к базе данных или внешнему API. Это медленно и дорого. Кэширование позволяет:
- переиспользовать результат fetch-запроса между рендерами;
- переиспользовать уже отрендеренный RSC Payload;
- снизить нагрузку на бэкенд и ускорить отдачу страниц.
Уровни кэширования
- Request memoization — в рамках одного рендера дерева компонентов одинаковые
fetch-запросы дедуплицируются автоматически. - Data cache — результаты
fetchмогут сохраняться между запросами и даже между деплоями, пока не будет вызвана revalidation. - Full route cache — HTML и RSC Payload для статических маршрутов кэшируются на сервере.
- Router cache (client-side) — на клиенте кэшируются уже посещённые сегменты маршрута, чтобы навигация была мгновенной.
Revalidation
Revalidation — это процесс обновления устаревших данных в кэше. Есть два основных подхода:
- Time-based (по времени) — данные считаются актуальными в течение заданного периода, после чего фоново обновляются при следующем запросе.
- On-demand (по требованию) — кэш инвалидируется вручную сразу после изменения данных, например после сохранения формы или webhook-события.
// Пример time-based revalidation при fetch на сервере
async function getPosts() {
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 }, // обновлять кэш не чаще раза в 60 секунд
});
return res.json();
}
// Пример on-demand revalidation после мутации данных
import { revalidateTag } from 'next/cache';
async function createPost(data) {
await db.posts.create(data);
// помечаем кэш с тегом 'posts' как устаревший
revalidateTag('posts');
}
Важные нюансы
- Кэш можно помечать тегами (
next.tags), чтобы точечно инвалидировать только связанные данные. no-storeв опциях fetch полностью отключает кэширование для этого запроса.- Server Components сами по себе не хранят состояние между запросами — кэшируются именно данные и результат рендеринга, а не сам компонент как объект.
- Revalidation не гарантирует мгновенное обновление у всех пользователей одновременно — при time-based подходе возможна кратковременная выдача устаревших данных (stale-while-revalidate).
Итог
Кэширование и revalidation в RSC — это способ балансировать между свежестью данных и производительностью: кэш ускоряет отдачу, а revalidation следит за тем, чтобы пользователи не видели сильно устаревшую информацию.
Что хочет услышать интервьюер
Понимание, что RSC рендерятся на сервере и это создаёт потребность в кэшировании результатов
Знание разницы между кэшированием данных (fetch) и кэшированием отрендеренного вывода (route cache)
Умение объяснить разницу между time-based и on-demand revalidation
Знание конкретных механизмов на примере Next.js (revalidate, revalidateTag, no-store)
Понимание, что кэш и state компонента — разные вещи
Пример: Time-based revalidation
async function getPosts() {
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 }, // обновлять кэш не чаще раза в 60 секунд
});
return res.json();
}
Пример: On-demand revalidation по тегу
import { revalidateTag } from 'next/cache';
async function createPost(data) {
await db.posts.create(data);
// помечаем кэш с тегом 'posts' как устаревший
revalidateTag('posts');
}
Типичные ошибки
Путают кэширование React Server Components с кэшированием клиентского состояния (useState/useMemo)
Не знают, что fetch-запросы дедуплицируются в рамках одного рендера автоматически
Считают, что revalidation происходит мгновенно у всех пользователей сразу
Не различают уровни кэша (data cache, full route cache, router cache)
Забывают, что 'no-store' отключает кэш полностью, а не просто уменьшает время жизни


